﻿using System;

using System.Collections.Generic;
using System.Text;
using PasswordSafe.Classes;
using System.Xml;

namespace PasswordSafe.Xml
{
    public class PasswordWriter : IDisposable
    {
        public string Write(IEnumerable<PasswordCategory> categories, IEnumerable<PasswordData> passwords)
        {
            StringBuilder xml = new StringBuilder();
            XmlWriterSettings settings = new XmlWriterSettings();
            using (XmlWriter writer = XmlTextWriter.Create(xml, settings))
            {
                writer.WriteStartElement("passwordsafe");
                writer.WriteStartElement("categories");
                WriteCategories(writer, categories);
                writer.WriteEndElement();
                writer.WriteStartElement("passwords");
                WritePasswords(writer, passwords);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }

            return xml.ToString();
        }

        private void WritePasswords(XmlWriter writer, IEnumerable<PasswordData> passwords)
        {
            foreach (PasswordData password in passwords)
            {
                writer.WriteStartElement("password");
                WriteValues(writer, password);
                writer.WriteEndElement();
            }
        }

        private void WriteValues(XmlWriter writer, PasswordData password)
        {
            foreach (string name in password.Values.AllKeys)
            {
                if (name.Equals("category", StringComparison.CurrentCultureIgnoreCase)) continue;
                string value = password.Values[name];
                writer.WriteAttributeString(name, value);
            }
            if (password.Category != null && !password.Category.IsDefault)
            {
                writer.WriteAttributeString("category", password.Category.Name);
            }
        }

        private void WriteCategories(XmlWriter writer, IEnumerable<PasswordCategory> categories)
        {
            foreach (PasswordCategory category in categories)
            {
                if (category.IsDefault) continue;
                writer.WriteStartElement("category");
                writer.WriteAttributeString("name", category.Name);
                if (!string.IsNullOrEmpty(category.Title) && category.Name != category.Title)
                {
                    writer.WriteAttributeString("title", category.Title);
                }
                WriteFields(writer, category);
                writer.WriteEndElement();
            }
        }

        private void WriteFields(XmlWriter writer, PasswordCategory category)
        {
            foreach (FieldInfo info in category.Fields)
            {
                if (info.Type == FieldType.Separator)
                {
                    writer.WriteStartElement("separator");
                    if (!string.IsNullOrEmpty(info.Title) && info.Title != info.Name)
                    {
                        writer.WriteAttributeString("title", info.Title);
                    }
                }
                else
                {
                    writer.WriteStartElement("field");
                    writer.WriteAttributeString("name", info.Name);
                    if (!string.IsNullOrEmpty(info.Title) && info.Title != info.Name)
                    {
                        writer.WriteAttributeString("title", info.Title);
                    }
                    if (info.Type != FieldType.String)
                    {
                        writer.WriteAttributeString("type", info.Type.ToString());
                    }
                }
                writer.WriteEndElement();
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
        }

        #endregion
    }
}
